home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 6
/
FM Towns Free Software Collection 6.iso
/
ms_dos
/
dsort
/
dstoptn.pre
< prev
next >
Wrap
Text File
|
1993-07-08
|
23KB
|
819 lines
page 96,132
;§∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞§
;§ §
;§ ディレクトリエントリ ソート ユーティリティ §
;§ §
;§ DSORT.EXE Ver1.30 §
;§ §
;§ Copyright (C) by 福地 邦雄 1991-1992. All rights reserved. §
;§∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞§
.MODEL SMALL,C
;
public options,usageout,dirlist,dirfind,strcopywild
extrn sweep:word,sortexec:word,recursive:word,dirgather:word
extrn dta:dword,srchname:dword,namebuff:dword,namebuffsiz:word
extrn dirtype:word,fattype:word,attribute:word,clustcount:word
extrn driveno:word,clustsize:word
extrn fatbuff:word,dirbuff:word,sortbuff:word,sortcount:word
extrn drvinf:byte,clustsect:word,subsearch:word
extrn sortfuncs:word,subchain:word,wildcard:byte,pathbuff:byte
extrn usagemsg:byte,_msgsize:abs
extrn abort:near
extrn errorno:word
;
PUBLIC setsortfunc,setsortobj,cmpdummy,cmpdirf,cmpfull,cmpname
PUBLIC cmpextn,cmpsize,cmpdate,cmptime,strncmp,chrtypes,pathsep
;
REVERSE equ 1
NORMAL equ 0
TAIL equ 1
HEAD equ 0
YES equ 1
NO equ 0
TAB equ 9
CR equ 0dh
LF equ 0ah
DEFAULT equ 031h
ARCHIVE equ 020h
SUBDIR equ 010h
VOLUME equ 008h
HIDDEN equ 004h
SYSTEM equ 002h
RDONLY equ 001h
;
.code
;
;------------------------------------------------------------------------------
;
; options
; オプション指定の評価とディレクトリのリストを取る
;
; TYPE near call
; IN AX アーギュメント数
; SS:BP アーギュメントポインタリストの先頭アドレス
; OUT 特になし
; 保存レジスタ ds
;
;------------------------------------------------------------------------------
;
options proc
;
cld
push ax
mov ah,2fh ; Disk Transfer Address 取得
int 21h
lea bx,[bx+1eh] ; DTAのファイル名オフセット
mov word ptr dta,bx
mov word ptr dta+2,es
pop bx
mov sortfuncs,offset _text:cmpdummy ; ダミーのソート比較関数セット
mov word ptr sortfuncs+2,NORMAL
mov si,offset sortfuncs+4
mov attribute,DEFAULT ; ソート対象属性のデフォルトセット
@do until
les di,[bp]
@cbegin
@case (byte ptr es:[di],=,'-'),S
call setsortfunc
@case (byte ptr es:[di],=,'+'),S
call setsortobj
@other
mov word ptr srchname,di ; ディレクトリ名リストの作成
mov word ptr srchname+2,es
call dirlist
@cend
add bp,4 ; 次のアーギュメントへ
dec bx
@doend (zf,on)
@if (si,=,offset sortfuncs+4)
mov word ptr [si],offset cmpfull ; デフォルトの比較関数セット
mov word ptr [si+2],NORMAL
lea si,[si+4]
@ifend
not attribute ; ソート対象属性を反転させたものを使う
mov word ptr [si],0 ; ソート比較関数リストのエンドマーク
les di,namebuff ; ディレクトリ名リストのエンドマーク
mov word ptr es:[di],0
@if (word ptr es:[0],=,0)
jmp usageout ; ディレクトリ無しの時、ヘルプ表示
@ifend
ret
;
options endp
;
;------------------------------------------------------------------------------
;
; usageout
; ヘルプメッセージを表示して終了
;
; TYPE near call
; IN なし
; OUT なし
; 保存レジスタ なし
;
;------------------------------------------------------------------------------
;
usageout proc
;
mov errorno,1
mov dx,offset usagemsg
mov cx,_msgsize
jmp abort
;
usageout endp
;
;------------------------------------------------------------------------------
;
; setsortfunc
; ソート機能指定オプションの評価と、比較関数リストの作成
;
; TYPE near call
; IN AL アーギュメント文字
; DS:SI 比較関数リストアドレス
; OUT SI += 4
; 保存レジスタ bx,cx,dx,di,bp,ds,es
;
;------------------------------------------------------------------------------
;
setsortfunc proc
;
inc di
@do repeat
mov al,es:[di]
inc di
@if (al,=,0)
@doexit
@ifend
@if (al,>=,'a'),S ; 昇順
mov word ptr [si+2],NORMAL
sub al,'a'-'A'
@else ; 降順
mov word ptr [si+2],REVERSE
@ifend
@cbegin
@case (al,=,'D'),S ; 最終更新日付
mov ax,offset _text:cmpdate
@case (al,=,'E'),S ; 拡張子 3バイト
mov ax,offset _text:cmpextn
@case (al,=,'F'),S ; フルネーム 11バイト
mov ax,offset _text:cmpfull
@case (al,=,'N'),S ; ファイル名 8バイト
mov ax,offset _text:cmpname
@case (al,=,'S'),S ; ファイルサイズ
mov ax,offset _text:cmpsize
@case (al,=,'T'),S ; 最終更新時刻
mov ax,offset _text:cmptime
@other
jmp usageout
@cend
mov [si],ax
lea si,[si+4]
@doend
ret
;
setsortfunc endp
;
;------------------------------------------------------------------------------
;
; setsortobj
; ソート対象選択オプション評価
;
; TYPE near call
; IN AL アーギュメント文字
; OUT なし
; 保存レジスタ AX以外
;
;------------------------------------------------------------------------------
;
setsortobj proc
;
inc di
@do repeat
mov al,es:[di]
inc di
@if (al,=,0)
@doexit
@ifend
@if (al,>=,'a'),S ; 先頭に
mov dirgather,HEAD
sub al,'a'-'A'
@else ; 末尾に
mov dirgather,TAIL
@ifend
@cbegin
@case (al,=,'G'),S ; ディレクトリの扱い
mov sortfuncs,offset _text:cmpdirf
mov ax,dirgather
mov sortfuncs+2,ax
@case (al,=,'T'),S ; 再帰呼び出し
mov recursive,YES
@case (al,=,'N'),S ; ソート無し
mov sortexec,NO
@case (al,=,'F'),S ; 掃き寄せ無し
mov sweep,NO
@case (al,=,'A'),S ; アーカイブ属性
xor attribute,ARCHIVE
@case (al,=,'D'),S ; ディレクトリ
xor attribute,SUBDIR
@case (al,=,'V'),S ; ボリュームラベル
xor attribute,VOLUME
@case (al,=,'S'),S ; システムファイル
xor attribute,SYSTEM
@case (al,=,'H'),S ; 隠しファイル
xor attribute,HIDDEN
@case (al,=,'R'),S ; 読み出しのみ可能
xor attribute,RDONLY
@other
jmp usageout
@cend
@doend
ret
;
setsortobj endp
;
;------------------------------------------------------------------------------
;
; cmpdummy
; ダミー比較ルーチン 必ず = で終了
;
; TYPE near call
; IN なし
; OUT AX=0 ZERO FLAG=1
; 保存レジスタ AX以外
;
;------------------------------------------------------------------------------
;
cmpdummy proc
;
xor ax,ax
ret
;
cmpdummy endp
;
;------------------------------------------------------------------------------
;
; cmpdirf
; ディレクトリ属性比較
;
; TYPE near call
; IN DS:0 エントリ1アドレス
; DX:0 エントリ2アドレス
; OUT AX ディレクトリ:通常= -1 通常:ディレクトリ= 1 その他 0
; 保存レジスタ AX以外
;
;------------------------------------------------------------------------------
;
cmpdirf proc
;
mov al,ds:[0bh] ; 属性バイトの取り出し
push es
mov es,dx
mov ah,es:[0bh]
pop es
and ax,01010h
cmp al,ah
ja dirfhead ; Dir:File
jb dirftail ; File:Dir
xor ax,ax ; 同じ属性
ret
dirfhead:
mov ax,-1
ret
dirftail:
mov ax,1
ret
;
cmpdirf endp
;
;------------------------------------------------------------------------------
;
; cmpfull
; フルネーム比較
;
; TYPE near call
; IN DS:0 エントリ1アドレス
; dx:0 エントリ2アドレス
; OUT AX エントリ1<エントリ2= -1 エントリ1=エントリ2= 0 エントリ1>エントリ2= 1
; 保存レジスタ bx,dx,bp,ds,es
;
;------------------------------------------------------------------------------
;
cmpfull proc
;
mov cx,11
xor si,si
xor di,di
call strncmp
ret
;
cmpfull endp
;
;------------------------------------------------------------------------------
;
; cmpname
; ファイル名比較
;
; TYPE near call
; IN DS:0 エントリ1アドレス
; dx:0 エントリ2アドレス
; OUT AX エントリ1<エントリ2= -1 エントリ1=エントリ2= 0 エントリ1>エントリ2= 1
; 保存レジスタ bx,dx,bp,ds,es
;
;------------------------------------------------------------------------------
;
cmpname proc
;
mov cx,8
xor si,si
xor di,di
call strncmp
ret
;
cmpname endp
;
;------------------------------------------------------------------------------
;
; cmpextn
; 拡張子比較
;
; TYPE near call
; IN DS:0 エントリ1アドレス
; dx:0 エントリ2アドレス
; OUT AX エントリ1<エントリ2= -1 エントリ1=エントリ2= 0 エントリ1>エントリ2= 1
; 保存レジスタ bx,dx,bp,ds,es
;
;------------------------------------------------------------------------------
;
cmpextn proc
;
mov si,8 ; 拡張子位置
mov di,si
mov cx,3
call strncmp
ret
;
cmpextn endp
;
;------------------------------------------------------------------------------
;
; cmpsize
; ファイルサイズ比較
;
; TYPE near call
; IN DS:0 エントリ1アドレス
; DX:0 エントリ2アドレス
; OUT AX エントリ1<エントリ2= -1 エントリ1=エントリ2= 0 エントリ1>エントリ2= 1
; 保存レジスタ bx,dx,si,di,bp,ds,es
;
;------------------------------------------------------------------------------
;
cmpsize proc
;
push es
mov es,dx
mov ax,es:[1ch] ; エントリ2のファイルサイズ4バイト
mov cx,es:[1eh]
pop es
cmp cx,ds:[1eh] ; エントリ1と比較
ja sizeabove
jb sizebelow
cmp ax,ds:[1ch]
ja sizeabove
jb sizebelow
xor ax,ax
ret
sizeabove:
mov ax,-1
ret
sizebelow:
mov ax,1
ret
;
cmpsize endp
;
;------------------------------------------------------------------------------
;
; cmpdate
; 最終更新日付比較
;
; TYPE near call
; IN DS:0 エントリ1アドレス
; DX:0 エントリ2アドレス
; OUT AX エントリ1<エントリ2= -1 エントリ1=エントリ2= 0 エントリ1>エントリ2= 1
; 保存レジスタ bx,dx,si,di,bp,ds,es
;
;------------------------------------------------------------------------------
;
cmpdate proc
;
mov ax,ds:[18h]
push es
mov es,dx
cmp ax,es:[18h]
pop es
ja dateabove
jb datebelow
xor ax,ax
ret
dateabove:
mov ax,1
ret
datebelow:
mov ax,-1
ret
;
cmpdate endp
;
;------------------------------------------------------------------------------
;
; cmptime
; 最終更新時刻比較
;
; TYPE near call
; IN DS:0 エントリ1アドレス
; DX:0 エントリ2アドレス
; OUT AX エントリ1<エントリ2= -1 エントリ1=エントリ2= 0 エントリ1>エントリ2= 1
; 保存レジスタ bx,dx,si,di,bp,ds,es
;
;------------------------------------------------------------------------------
;
cmptime proc
;
mov ax,ds:[16h]
push es
mov es,dx
cmp ax,es:[16h]
pop es
ja timeabove
jb timebelow
xor ax,ax
ret
timeabove:
mov ax,1
ret
timebelow:
mov ax,-1
ret
;
cmptime endp
;
;------------------------------------------------------------------------------
;
; strncmp
; 文字列比較 漢字対応 漢字はANKより大きい
;
; TYPE near call
; IN CX 比較サイズ
; DS:SI エントリ1アドレス
; ES:DI エントリ2アドレス
; OUT AX エントリ1<エントリ2= -1 エントリ1=エントリ2= 0 エントリ1>エントリ2= 1
; 保存レジスタ bx,dx,si,di,bp,ds,es
;
;------------------------------------------------------------------------------
;
strncmp proc uses bx es
;
cld
mov es,dx
@do until
dec cx
mov ax,[si] ; エントリ1 1文字取得
inc si
call chrtypes
@if (zf,off)
dec cx
inc si
@ifend
;
mov bx,ax
mov ax,es:[di] ; エントリ2 1文字取得
inc di
call chrtypes
@if (zf,off)
inc di
@ifend
cmp bx,ax ; 比較
ja strabove
jb strbelow
or cx,cx
@doend (zf,on),or,(sf,on)
;
xor ax,ax
streturn:
ret
;
strabove:
mov ax,1
jmp streturn
strbelow:
mov ax,-1
jmp streturn
;
strncmp endp
;
;------------------------------------------------------------------------------
;
; chrtypes
; 漢字判定
;
; TYPE near call
; IN AX 文字コード AL=第一バイト
; OUT AX 判定後コード ANK:AH=0
; ZERO FLAG AHのTEST結果
; 保存レジスタ AX以外
;
;------------------------------------------------------------------------------
;
chrtypes proc
;
cmp al,081h
jb chrank
cmp al,0a0h
jb chrsjis
cmp al,0e0h
jb chrank
cmp al,0fch
jbe chrsjis
chrank:
xor ah,ah
ret
chrsjis:
xchg ah,al
test ah,ah
ret
;
chrtypes endp
;
;------------------------------------------------------------------------------
;
; dirlist
; 全てのディレクトリ名を検索して、そのパス名をバッファに格納する
; ワイルドカード対応 FUNCTION 4EH,4FH
;
; TYPE near call
; IN 検索情報構造体
; OUT ディレクションフラグ アップ方向
; 保存レジスタ bp,ds
;
;------------------------------------------------------------------------------
;
dirlist proc uses bx si
local copysiz,fnamsiz,saveds
;
mov saveds,ds ;DS セーブ
les di,srchname ;パス名の長さと、最終位置を獲得
mov cx,0ffffh
cld
xor al,al
repne scasb
not cx
dec cx
mov fnamsiz,cx
mov di,word ptr srchname
call pathsep ; パス名中の最後の'\'位置を獲得
mov copysiz,cx ; バッファへの共通コピーサイズをセット
mov di,word ptr srchname
mov dx,es:[di]
@cbegin
@case (zf,on) ; セパレータなし
@if (dx,=,'.'),or,(dx,=,'..') ; カレント/親?
jmp parentdir
@ifend
@case (fnamsiz,=,1),and,(dl,=,'\'),S ; ルート指定か?
mov ah,19h ; カレントドライブ取得
int 21h
add al,'A' ; ドライブ名作成
mov ah,':'
jmp rootpath
@case (cx,=,2),S ; カレント/親 指定か?
@if (dh,=,':')
@if (fnamsiz,=,2)
sub namebuffsiz,4 ; ディレクトリ名バッファサイズチェック
@if (cf,on)
add namebuffsiz,4
jmp srchout
@ifend
cld
les di,namebuff
mov ax,dx ; ドライブ名
stosw
mov ax,'.' ; カレントディレクトリ指定
stosw
mov word ptr namebuff,di ; 新オフセット設定
jmp srchout
@ifend
@if (fnamsiz,<=,4)
mov ax,es:[di+2]
@if (ax,=,'.'),or,(ax,=,'..')
jmp parentdir
@ifend
@ifend
@ifend
@case (fnamsiz,=,3),and,(word ptr es:[di+1],=,'\:'),S ; ルート指定か?
mov ax,dx
rootpath:
sub namebuffsiz,3 ; バッファ残りサイズ確認
@if (cf,on)
add namebuffsiz,3
jmp srchout
@ifend
cld
les di,namebuff ; ドライブ名のみセット
stosw
xor al,al
stosb
mov word ptr namebuff,di
jmp srchout
@cend
;
mov ah,4eh ;最初のファイル名検索ファンクション
mov cx,037h ;ボリュームラベル以外すべて
lds dx,srchname
int 21h
@do while,(cf,off)
mov ds,saveds ; DS 復元
les di,dta
@if (byte ptr es:[di-9],on,10h) ;ディレクトリかどうかのチェック
mov dx,es:[di] ; 再帰処理のさいに '.' '..' を外す
@if (subsearch,=,YES)
@if (dx,=,'.'),or,(dx,=,'..')
jmp skipperiod
@ifend
@ifend
mov cx,13 ;DTA上のファイル名から、長さを獲得
xor al,al
cld
repne scasb
sub cx,13
neg cx
mov fnamsiz,cx ;ファイル名長さをセーブ
add cx,copysiz ;残りバッファサイズのチェックと更新
sub namebuffsiz,cx
@if (cf,on)
add namebuffsiz,cx ;不足
jmp short srchout
@ifend
les di,namebuff ;共通パス名のコピー
lds si,srchname
mov cx,copysiz
rep movsb
mov ds,saveds ;ファイル名のコピー
lds si,dta
mov cx,fnamsiz
rep movsb
mov ds,saveds
mov word ptr namebuff,di ;新オフセットの設定
@ifend
skipperiod:
mov ah,4fh ;次のファイル名検索ファンクション
lds dx,srchname
mov cx,037h
int 21h ;見つかればパス名セーブ
@doend
mov ds,saveds
srchout:
ret
;
parentdir:
cld ; パス名長さを調べる
les di,srchname
xor ax,ax
mov cx,-1
repne scasb
not cx
sub namebuffsiz,cx
@if (cf,on)
add namebuffsiz,cx ;不足
jmp short srchout
@ifend
les di,namebuff ;ファイル名のコピー
lds si,srchname
rep movsb
mov ds,saveds ; DS 復元
mov word ptr namebuff,di ;新オフセットの設定
jmp short srchout
;
dirlist endp
;
;------------------------------------------------------------------------------
;
; pathsep
; パス名を調べて一番最後の':'か'\'までのバイト数を通知する
;
; TYPE near call
; IN CX パス名長さ
; ES:DI パス名の先頭アドレス
; OUT CX & ZERO FLAG 最後の':'or'\'までのバイト数 及び 0か?
; DIR FLAG アップ方向
; 保存レジスタ bx,si,bp,ds,es
;
;------------------------------------------------------------------------------
;
pathsep proc
;
@if (cx,/=,0) ; 0 でない時
push cx ; 長さをセーブ
xor dx,dx ; 位置を初期化
@do until
mov al,es:[di] ; 文字獲得
inc di
@cbegin
@case (al,=,':'),or,(al,=,'\'),S ; セパレータならば位置を記憶
mov dx,cx
@case (al,<,81h),or,(al,>,0fch),S ; α/N なにもしない
@case (al,>=,0a0h),and,(al,<=,0dfh),S ; カナ なにもしない
@other ; 漢字 第二バイト分を進める
inc di
dec cx ; 残り0なら終了
jz analysend
@cend
dec cx ; 残り0なら終了
@doend (zf,on)
analysend:
pop cx ; パス名長を復元
@if (dx,/=,0),S ; セパレータが有った時
dec dx ; DX にはパス名最後からのオフセット
sub cx,dx ; 先頭からのオフセットに直す
@else
xor cx,cx ; セパレータが無い時は0
@ifend
@ifend
ret
;
pathsep endp
;
;------------------------------------------------------------------------------
;
; dirfind
; パス名をもとにディレクトリかを調べ、ディレクトリの開始クラスタ
; と、存在するドライブ番号を通知する
;
; TYPE near call
; IN ES:DI パス名の先頭アドレス
; OUT AX ディレクトリの開始クラスタ番号
; DL ドライブ番号
; CARRY FLAG ディレクトリ属性 0:DIR 1:OTHERまたはルートでファイル無し
; 保存レジスタ bp,ds
;
;------------------------------------------------------------------------------
;
dirfind proc
;
call strcopywild ; 検索用パス名の作成
;
mov ah,2fh ; DTA 取得
int 21h
;
mov ah,4eh ; ファイル検索
mov cx,3fh
int 21h
@if (cf,off) ; 見つかった
mov ax,es:[bx+0fh] ; ディレクトリの開始クラスタ取得
xor dx,dx
mov dl,es:[bx] ; ディレクトリのドライブ番号取得
@ifend
ret
;
dirfind endp
;
;------------------------------------------------------------------------------
;
; strcopywild
; 指定されたパス名をPATHBUFFにコピーし、ワイルドカードを付加する
;
; TYPE near call
; IN ES:DI パス名の先頭アドレス
; OUT PATHBUFF
; ES:DI PATHBUFFのアドレス
; 保存レジスタ bp,ds
;
;------------------------------------------------------------------------------
;
strcopywild proc
;
cld ; パス名長さを調べる
mov cx,-1
xor ax,ax
mov si,di
repne scasb
not cx
dec cx
mov ax,ds ; パス名をPATHBUFFにコピー
mov dx,es
mov ds,dx
mov es,ax
mov di,offset pathbuff
mov dx,di
rep movsb
mov ds,ax ; ワイルドカード指定を付加
mov cx,5
mov si,offset wildcard
rep movsb
;
mov di,offset pathbuff
ret
;
strcopywild endp
;
end